import axios from 'axios';

// 定义净值记录类型
export interface NetWorthRecord {
  id: string;
  date: string;
  value: number;
}

// 定义爬虫配置类型
export interface CrawlerConfig {
  bankName: string;
  url: string;
  productCode?: string;
}

// 定义银行解析器接口
interface BankParser {
  validateUrl: (url: string) => boolean;
  parseNetWorthData: (html: string) => Promise<NetWorthRecord[]>;
}

// 格式化日期字符串
const formatDate = (dateStr: string): string => {
  // 检查是否为有效日期字符串
  if (!dateStr || typeof dateStr !== 'string') {
    return '';
  }
  
  // 移除日期字符串中的空格和特殊字符
  const cleanDateStr = dateStr.replace(/\s+/g, '');
  
  // 检查是否是有效的日期格式
  const isValidDate = (dateStr: string): boolean => {
    return /\d{4}[-/年]\d{1,2}[-/月]\d{1,2}|^\d{8}$/.test(dateStr);
  };
  
  // 如果不是有效的日期格式，返回空字符串
  if (!isValidDate(cleanDateStr)) {
    return '';
  }
  
  // 支持的日期格式及其对应的正则表达式和格式化函数
  const patterns = [
    // 标准格式：2023-01-01 或 2023/01/01 或 2023年01月01日
    {
      regex: /(\d{4})[-/年](\d{1,2})[-/月](\d{1,2})日?/,
      formatter: (matches: RegExpMatchArray) => `${matches[1]}-${matches[2].padStart(2, '0')}-${matches[3].padStart(2, '0')}`
    },
    // 短年份格式：23-01-01 或 23/01/01
    {
      regex: /(\d{2})[-/](\d{1,2})[-/](\d{1,2})/,
      formatter: (matches: RegExpMatchArray) => {
        const year = parseInt(matches[1]);
        const fullYear = year > 50 ? 1900 + year : 2000 + year;
        return `${fullYear}-${matches[2].padStart(2, '0')}-${matches[3].padStart(2, '0')}`;
      }
    },
    // 中文格式：2023年1月1日
    {
      regex: /(\d{4})年(\d{1,2})月(\d{1,2})日?/,
      formatter: (matches: RegExpMatchArray) => `${matches[1]}-${matches[2].padStart(2, '0')}-${matches[3].padStart(2, '0')}`
    },
    // 日期顺序反转：01-01-2023 或 01/01/2023
    {
      regex: /(\d{1,2})[-/](\d{1,2})[-/](\d{4})/,
      formatter: (matches: RegExpMatchArray) => `${matches[3]}-${matches[1].padStart(2, '0')}-${matches[2].padStart(2, '0')}`
    },
    // 仅数字格式：20230101
    {
      regex: /(\d{4})(\d{2})(\d{2})/,
      formatter: (matches: RegExpMatchArray) => `${matches[1]}-${matches[2]}-${matches[3]}`
    }
  ];

  // 尝试每种格式
  for (const pattern of patterns) {
    const matches = cleanDateStr.match(pattern.regex);
    if (matches) {
      return pattern.formatter(matches);
    }
  }

  // 如果没有匹配的格式，返回空字符串
  return '';
};

// 生成模拟数据（用于开发测试）
const generateMockData = (productCode: string = 'MOCK'): NetWorthRecord[] => {
  const records: NetWorthRecord[] = [];
  const today = new Date();
  
  for (let i = 0; i < 7; i++) {
    const date = new Date(today);
    date.setDate(date.getDate() - i);
    records.push({
      id: `${productCode}-${i}`,
      date: date.toISOString().split('T')[0],
      value: 1 + Math.random() * 0.1
    });
  }
  
  return records;
};

// 中国银行数据解析器
const BOCParser: BankParser = {
  validateUrl: (url: string): boolean => {
    return url.includes('bankofchina.com') && (url.includes('wmpnetworth') || url.includes('wealth'));
  },

  parseNetWorthData: async (html: string): Promise<NetWorthRecord[]> => {
    const records: NetWorthRecord[] = [];
    let lastValidDate = ''; // 用于记录最后一个有效的日期
    
    try {
      // 查找动态生成的数据
      const dataPattern = /document\.write\('<td[^>]*>([^<]+)<\/td>'\)/g;
      const rowData: string[] = [];
      let match;
      
      while ((match = dataPattern.exec(html)) !== null) {
        if (match[1]) {
          rowData.push(match[1].trim());
        }
      }

      // 处理找到的数据
      if (rowData.length > 0) {
        // 每行8个字段
        const FIELDS_PER_ROW = 8;
        for (let i = FIELDS_PER_ROW; i < rowData.length; i += FIELDS_PER_ROW) {
          const productCode = rowData[i];
          const productName = rowData[i + 1];
          const netWorthValue = parseFloat(rowData[i + 2]);
          let date = rowData[i + 7];
          
          // 检查日期格式
          const formattedDate = formatDate(date);
          
          // 如果日期格式化后为空，使用最后一个有效日期
          if (!formattedDate && lastValidDate) {
            date = lastValidDate;
          } else if (formattedDate) {
            lastValidDate = formattedDate;
          }

          if (!isNaN(netWorthValue) && lastValidDate) {
            records.push({
              id: `${productCode || 'unknown'}-${lastValidDate}-${i}`,
              date: lastValidDate,
              value: netWorthValue
            });
          }
        }
      }

      // 如果没有找到动态生成的数据，尝试从静态HTML中解析
      if (records.length === 0) {
        const parser = new DOMParser();
        const doc = parser.parseFromString(html, 'text/html');
        const tables = doc.querySelectorAll('table');
        let lastValidDate = '';
        
        for (const table of Array.from(tables)) {
          const rows = table.querySelectorAll('tr');
          
          // 先扫描一遍找出所有有效的日期行
          const dateRows = new Map<number, string>();
          for (let i = 0; i < rows.length; i++) {
            const cells = rows[i].querySelectorAll('td');
            if (cells.length >= 2) {
              // 检查是否是日期行
              for (let j = 0; j < cells.length; j++) {
                const cellText = cells[j]?.textContent?.trim() || '';
                const formattedDate = formatDate(cellText);
                if (formattedDate) {
                  dateRows.set(i, formattedDate);
                  lastValidDate = formattedDate;
                  break;
                }
              }
            }
          }
          
          // 再次扫描处理所有行
          for (let i = 0; i < rows.length; i++) {
            const cells = rows[i].querySelectorAll('td');
            if (cells.length >= 2) {
              // 查找净值
              let netWorthValue = null;
              for (let j = 0; j < cells.length; j++) {
                const cellText = cells[j]?.textContent?.trim() || '';
                const value = parseFloat(cellText);
                if (!isNaN(value) && cellText.length < 10) { // 避免将日期误认为净值
                  netWorthValue = value;
                  break;
                }
              }
              
              // 确定日期
              let currentDate = '';
              
              // 1. 检查当前行是否有日期
              if (dateRows.has(i)) {
                currentDate = dateRows.get(i) || '';
              } 
              // 2. 检查上一行是否有日期
              else if (dateRows.has(i - 1)) {
                currentDate = dateRows.get(i - 1) || '';
              }
              // 3. 使用最后一个有效日期
              else if (lastValidDate) {
                currentDate = lastValidDate;
              }
              
              if (netWorthValue !== null && currentDate) {
                records.push({
                  id: `static-${currentDate}-${i}`,
                  date: currentDate,
                  value: netWorthValue
                });
              }
            }
          }
        }
      }
      
      // 去重：可能有重复的记录
      const uniqueRecords = new Map<string, NetWorthRecord>();
      records.forEach(record => {
        const key = `${record.date}-${record.value}`;
        if (!uniqueRecords.has(key)) {
          uniqueRecords.set(key, record);
        }
      });
      
      return Array.from(uniqueRecords.values());
    } catch (error) {
      console.error('解析HTML失败:', error);
    }
    
    return records;
  }
};

// 建设银行数据解析器
const CCBParser: BankParser = {
  validateUrl: (url: string): boolean => {
    return url.includes('ccb.com') && url.includes('wealth');
  },
  parseNetWorthData: async (html: string): Promise<NetWorthRecord[]> => {
    // TODO: 实现建设银行的数据解析逻辑
    return [];
  }
};

// 支持的银行解析器映射
const bankParsers: { [key: string]: BankParser } = {
  'BOC': BOCParser,
  'CCB': CCBParser
};

// 爬取净值数据的主函数
export const crawlNetWorthData = async (config: CrawlerConfig): Promise<NetWorthRecord[]> => {
  try {
    // 验证URL格式
    const parser = bankParsers[config.bankName];
    if (!parser || !parser.validateUrl(config.url)) {
      throw new Error('不支持的URL格式或银行类型');
    }

    let html: string;
    
    try {
      console.log('尝试直接请求URL:', config.url);
      // 尝试直接请求（如果目标服务器支持CORS）
      const response = await axios.get(config.url, {
        headers: {
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
          'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
          'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
          'Referer': 'https://www.bankofchina.com'
        }
      });
      html = response.data;
    } catch (error) {
      console.warn('直接请求失败，尝试使用代理服务...', error);
      
      // 使用开发环境代理
      const proxyUrl = process.env.NODE_ENV === 'development'
        ? `/api/proxy?url=${encodeURIComponent(config.url)}`
        : config.url;
      
      console.log('使用代理URL:', proxyUrl);
      const response = await axios.get(proxyUrl);
      html = response.data;
    }

    console.log('获取到HTML内容，长度:', html.length);
    
    // 使用对应银行的解析器处理数据
    let records = await parser.parseNetWorthData(html);
    console.log('解析到的记录数:', records.length);
    
    // 如果无法获取真实数据，使用模拟数据（仅用于演示）
    if (records.length === 0) {
      if (process.env.NODE_ENV === 'development') {
        console.warn('无法获取真实数据，使用模拟数据进行演示');
        records = generateMockData(config.productCode);
      } else {
        console.warn('无法获取真实数据');
      }
    }
    
    return records;
  } catch (error) {
    console.error('爬取数据失败:', error);
    throw error;
  }
};